package org.carry.god.framework.common.exception.utils;

import lombok.extern.slf4j.Slf4j;
import org.carry.god.framework.common.exception.ErrorCode;
import org.carry.god.framework.common.exception.ServiceException;

/**
 * @author wanglei
 */
@Slf4j
public class ServiceExceptionUtil {
    /**
     * 私有构造方法，防止被实例化
     */
    private ServiceExceptionUtil() {
    }

    public static ServiceException exception(ErrorCode errorCode, Object... params) {
        return exception(errorCode.getCode(), errorCode.getMessage(), params);
    }

    public static ServiceException exception(Integer code, String messagePattern, Object... params) {
        String message = doFormat(code, messagePattern, params);
        return new ServiceException(code, message);
    }

    /**
     * 根据错误代码和消息模板格式化错误消息。
     * 该方法通过替换消息模板中的占位符（{}）来生成最终的错误消息。每个占位符会被对应的参数值替换。
     * 如果参数数量不足或占位符使用不当，会记录错误日志。
     *
     * @param code 错误代码，用于标识特定的错误。
     * @param messagePattern 错误消息的模板，包含一个或多个占位符（{}）。
     * @param params 参数数组，用于填充占位符。
     * @return 格式化后的错误消息。
     */
    public static String doFormat(int code, String messagePattern, Object... params) {
        // 初始化StringBuilder，估计长度为消息模板长度加上额外的50个字符
        StringBuilder buff = new StringBuilder(messagePattern.length() + 50);
        // 初始化索引i用于查找占位符
        int i = 0;
        int j;
        int l;
        // 遍历参数数组
        for (l = 0; l < params.length; l++) {
            // 在消息模板中查找下一个占位符的位置
            j = messagePattern.indexOf("{}", i);
            // 如果找不到占位符，表示参数过多或占位符使用错误
            if (j == -1) {
                // 记录错误日志
                log.error("[doFormat][参数过多：错误码({})|错误内容({})|参数({})", code, messagePattern, params);
                // 如果尚未添加任何内容，直接返回消息模板
                if (i == 0) {
                    return messagePattern;
                } else {
                    // 否则，添加剩余部分的消息模板并返回
                    buff.append(messagePattern.substring(i));
                    return buff.toString();
                }
            } else {
                // 如果找到占位符，先添加占位符前的部分消息模板
                buff.append(messagePattern, i, j);
                // 然后添加对应的参数值
                buff.append(params[l]);
                // 更新索引i，准备处理下一个占位符
                i = j + 2;
            }
        }
        // 检查是否还有未被替换的占位符
        if (messagePattern.indexOf("{}", i) != -1) {
            // 如果有，表示参数过少
            // 记录错误日志
            log.error("[doFormat][参数过少：错误码({})|错误内容({})|参数({})", code, messagePattern, params);
        }
        // 添加剩余部分的消息模板
        buff.append(messagePattern.substring(i));
        // 返回格式化后的错误消息
        return buff.toString();
    }

}
